/**
 * WangSong 2009-6-21 下午09:18:40 修改为连续读取方式
 * WangSong 2009-9-23 下午05:53:41 修改readAll读取的bug，增加了replace方法
 */
package cn.biplam.common.file;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

import cn.biplam.common.wrapper.ErrorMessage;

/**
 * 文本文件读写操作,每次读取或写入一行<BR>
 * 使用方法：<UL>
 * <LI>读取文件前,必须调用prepareRead()准备数据环境
 * <LI><Font color=red>读取文件后，必须调用close()关闭缓冲区</font>
 * <LI>read(char[])字节读,readln()读取一行
 * <LI>文件结束时：read()返回-1,readln()返回null
 * </UL>
 * @author 	WangSong 2009-3-12 上午09:42:51
 * @version 1.0
 */
public class TxtFile{

	//指定文件路径和名称
	private String sPath;
	private String sFileName;
	private File mFile;
	private BufferedReader bufread;
	private boolean ignoreEnter=true;

	/**
	 * 功能：构造方法
	 * @param sPath  	文件路径
	 * @param sFileName  文件名
	 */
	public TxtFile(String sPath,String sFileName){
		this.sPath = sPath;
		this.sFileName = sFileName;
		this.mFile = new File(this.sPath+this.sFileName);
	}

	/**
	 * 准备好读缓冲区(在读取文件之前，必须先调用本方法)
	 * @throws ErrorMessage
	 */
	public void prepareRead() throws ErrorMessage{
		if(this.bufread==null){
			try{
				FileReader fileread = new FileReader(mFile);
				this.bufread = new BufferedReader(fileread);
			}catch(IOException e) {
				throw new ErrorMessage(e);
			}
		}else{
			throw new ErrorMessage("TxtFile already prepare for read!");
		}
	}

	/**
	 * 字节读取
	 * @param buf
	 * @return
	 * @throws ErrorMessage
	 */
	public int read(char[] buf) throws ErrorMessage{
		try {
			return bufread.read(buf);
		} catch (IOException e) {
			throw new ErrorMessage(e);
		}
	}

	/**
	 * 读取一行
	 * @return
	 * @throws ErrorMessage
	 */
	public String readln() throws ErrorMessage{
		try {
			return bufread.readLine();
		} catch (Exception e) {
			throw new ErrorMessage(e);
		}
	}
	
	/**
	 * 读取整个文件
	 * @return
	 * @throws ErrorMessage
	 */
	public String readAll() throws ErrorMessage{
		StringBuilder  sb = new StringBuilder();
		try {
			try {
				int cc;
				while((cc=bufread.read())!=-1){
					if(cc!=13)
						sb.append((char)cc);
					else if(this.ignoreEnter)
						sb.append("\r\n");
					sb.append(readln());
				}
			} catch (IOException e) {
				throw new ErrorMessage(e);
			}
		}finally{
			close();
		}
		return sb.toString();
	}

	/**
	 * 关闭文件读取缓冲区
	 * @throws ErrorMessage
	 */
	public void close() throws ErrorMessage{
		try {
			this.bufread.close();
		} catch (IOException e) {
			throw new ErrorMessage(e);
		}
	}

	/** 
	 * 功能 创建文本文件
	 * @throws IOException 
	 * 
	 */
	public void create() throws IOException {

		File mFoder = new File(this.sPath);
		if(!mFoder.exists()){
			mFoder.mkdirs();
		}
		if (!mFile.exists()) {
			mFile.createNewFile();
		}
	}

	/** 
	 * 写文件
	 */
	public void writeln(String sContent) throws ErrorMessage {

		FileWriter writer = null;
		try {
			//如文件夹不存在先创建
			this.create();
			//在文件尾写
			writer = new FileWriter(this.mFile, true);
			writer.write(sContent+"\r\n");
		} catch (IOException e) {
			throw new ErrorMessage(e);
		} finally{
			if(writer!=null){
				try {
					writer.close();
				} catch (IOException e) {
					throw new ErrorMessage(e);
				}
			}
		}
	}

	/** 
	 * 将文件中指定内容的第一行替换为其它内容
	 * @param oldStr 查找内容
	 * @param replaceStr 替换内容
	 * @throws ErrorMessage 
	 */
	public void replaceTxtByStr(String oldStr,String replaceStr) throws ErrorMessage {

		String temp = "";
		try {
			FileInputStream fis = new FileInputStream(this.mFile);
			InputStreamReader isr = new InputStreamReader(fis);
			BufferedReader br = new BufferedReader(isr);
			StringBuffer buf1 = new StringBuffer();

			// 保存该行前面的内容
			for (int j = 1; (temp = br.readLine()) != null
			&& !temp.equals(oldStr) ; j++) {
				if(temp.length()<1 || temp.charAt(temp.length()-1)=='\r'){
					continue;
				}
				buf1.append(temp);
				buf1.append(System.getProperty("line.separator"));
			}

			StringBuffer buf=new StringBuffer();
			
			// 保存该行后面的内容
			while ((temp = br.readLine()) != null) {
				if(temp.length()<1 || temp.charAt(temp.length()-1)=='\r'){
					continue;
				}
				buf.append(temp);
				buf.append(System.getProperty("line.separator"));
			}

			br.close();
			FileOutputStream fos = new FileOutputStream(this.mFile);
			PrintWriter pw = new PrintWriter(fos);
			pw.write(buf1.toString());
			if(buf.length()>0){
				pw.write(replaceStr);
				pw.write(System.getProperty("line.separator"));
				pw.write(buf.toString());
			}
			pw.flush();
			pw.close();
		} catch (IOException e) {
			throw new ErrorMessage(e);
		}
	}

	/** 
	 * 将文件中某个字符串替换为其它内容
	 * @param oldStr 查找内容
	 * @param replaceStr 替换内容
	 * @throws ErrorMessage 
	 */
	public void replace(String oldStr,String replaceStr) throws ErrorMessage {

		this.prepareRead();
		String temp = this.readAll();
		temp=temp.replaceAll(oldStr, replaceStr);
		try {
			FileOutputStream fos = new FileOutputStream(this.mFile);
			PrintWriter pw = new PrintWriter(fos);
			pw.write(temp);
			pw.flush();
			pw.close();
		} catch (IOException e) {
			throw new ErrorMessage(e);
		}
	}

	/**
	 * 设置全部时,是否忽略行尾的回车
	 * @param ignoreEnter
	 */
	public void setIgnoreEnter(boolean ignoreEnter) {
		this.ignoreEnter = ignoreEnter;
	}
	
	/**
	 * 返回该文件是否可读
	 * @return boolean
	 */
	public boolean canRead(){
		return mFile.canRead();
	}
}
